package com.example.myapplication.tools;

import com.example.myapplication.config.RfidConstant;

import java.util.Map;
import java.util.regex.Pattern;

public class RFIDWriteReadUtile {

    /**
     * 根据真实数据，转化为16进制
     * @param barcode
     * @return
     */
    public static String getWriteRfidDataByStr(String barcode){
        int state = 6;
        if(Pattern.matches("[1-9]{1}[0-9]{0,}", barcode)){
            try{
                System.out.println("数字格式");
                Long number = Long.parseLong(barcode);
                String hex = Long.toHexString(number);
                long l = 9219567894654654532L;
                if(hex.length()%2 == 1){
                    hex = "0" + hex;
                }
                return getWriteData(hex,3);
            }catch (Exception e){
                System.out.println("整形格式");
                state = 4;
            }
        }else if(Pattern.matches("[0-9]{1,}", barcode)){
            System.out.println("整形格式");
            state = 4;
        }else if(Pattern.matches("[A-Z]{1,}", barcode)){
            System.out.println("大写");
            state = 5;
        }else if(Pattern.matches("[0-9A-Z]{1,}", barcode)){
            System.out.println("大写和数字");
            state = 6;
        }else if(Pattern.matches("[0-9a-zA-Z]{1,}", barcode)){
            System.out.println("大小写和数字");
            state = 7;
        }
        String temp = str2bin(barcode,state);
        if(temp.length() == 0){
            return temp;
        }
        System.out.println(temp);
        temp = bin2hex(temp,state);
        return getWriteData(temp,state);
    }

    /**
     * 读取RFID标签内容
     * @param temp
     * @return
     */
    public static String readRfidDataByHex(String temp){
        if(temp.contains("6F020131")){
            int index = temp.indexOf("6F020131");
            temp = temp.substring(0, index);
        }
        if(temp.length() ==0){
            return "";
        }
        String firstStr = temp.substring(0, 2);

        int i1 = Integer.parseInt(firstStr, 16);
        String binStr = Integer.toBinaryString(i1);
        String s = "00000000" + binStr;
        s = s.substring(s.length() - 8);
        s = s.substring(0,4);
        String pianyi = String.valueOf(s.charAt(0));
        //27972ae
        String lengStr = "";
        int indexLast = 0;
        if("0".equals(pianyi)){
            lengStr = temp.substring(2, 4);
            indexLast = 4;
        }else{
            lengStr = temp.substring(4, 6);
            indexLast = 6;
        }


        s = s.substring(1);
        if("001".equals(s)){//整型
            int contentLength = Integer.parseInt(lengStr, 16);
            String content = temp.substring(indexLast, indexLast + contentLength * 2);
            Long i = Long.parseLong(content,16);
            return i+"";
        }else{
            int state = 0;
            if("010".endsWith(s)){//数字
                state = 4;
            }else if("011".endsWith(s)){//大写字母
                state = 5;
            }else if("100".endsWith(s)){//大写字母加数字
                state = 6;
            }else if("101".endsWith(s)){
                state = 7;
            }else{
                return "提示：标签未写入内容（格式不正确）";
            }
            int contentLength = Integer.parseInt(lengStr, 16);
            String content = temp.substring(indexLast, indexLast + contentLength * 2);
            String contentBin = hex2bin(content);
            return bin2str(contentBin,state);
        }

    }

    /**
     * 字符串转换为二进制字符串
     * @param barcode
     * @return
     */
    private static String str2bin(String barcode,int state){
        int length = barcode.length();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            String tempBar;
            tempBar = String.valueOf(barcode.charAt(i));
            String aa ="";
            switch(state){
                case 4:
                    aa = RfidConstant.map4.get(tempBar);
                    break;
                case 5:
                    aa = RfidConstant.map5.get(tempBar);
                    break;
                case 6:
                    aa = RfidConstant.map6.get(tempBar);
                    break;
                case 7:
                    aa = RfidConstant.map7.get(tempBar);
                    break;
                default:
                    return "";
            }
            System.out.print(aa+" ");
            sb.append(aa);
        }
        return sb.toString();
    }

    /**
     * 二进制字符串转化为16进制
     * @param input
     * @return
     */
    private static String bin2hex(String input,int state) {
        StringBuilder sb = new StringBuilder();
        String buwei = "00000000";
        if(state == 4){
            buwei = "11111111";
        }
        int cha = input.length()%8;
//        input += buwei.substring(0,cha);
        input += buwei.substring(cha);

        int len = input.length();

        for (int i = 0; i < len / 8; i++){
            //每4个二进制位转换为1个十六进制位
            String temp = input.substring(i * 8, (i + 1) * 8);
            int tempInt = Integer.parseInt(temp, 2);//11010010
            String a = Integer.toHexString(tempInt).toUpperCase();
            String tempHex = tempInt >15 ? a : "0"+a;
            sb.append(tempHex);
        }
        //11010000
        //11010010
        return sb.toString();
    }

    /**
     * 转换为最后数据  String
     * 传进来偶数长度的16进制数据，返回可以直接写入块的8*n的数据
     * @param state
     * @param data
     * @return
     */
    private static String getWriteData(String data, int state){
        String pianyi = "";
        String type = "";
        int dataLength = data.length()/2;
        switch(state){
            case 3://整型
                type = "001";
                break;
            case 4://数字
                type = "010";
                break;
            case 5://大写字母
                type = "011";
                break;
            case 6://大写字母加数字
                type = "100";
                break;
            case 7:
                type = "101";
                break;
            default:
                return "";
        }
        type += "0001";
        if((dataLength + 2)%4 == 0){//判断是否有偏移量
            type = "0" + type;
        }else{
            type = "1" + type;
            int pianyiSize = (dataLength + 3)%4;
            switch(pianyiSize){
                case 2:
                    data += "0000";
                    pianyi = "02";
                    break;
                case 3:
                    data += "00";
                    pianyi = "01";
                    break;
                case 0:
                    pianyi = "00";
                    break;
            }
        }
        String firstStr = Integer.toHexString(Integer.parseInt(type,2));
        String lenStr = dataLength <= 15 ? "0" + Integer.toHexString(dataLength) : Integer.toHexString(dataLength);
        String result = firstStr + "" + pianyi + "" + lenStr + data + "6F020131";
        return result.toUpperCase();
    }

    /**
     * 16进制字符串转化为二进制
     * @param input 16转二进制，不够8位用0补
     * @return
     */
    private static String hex2bin(String input){
        StringBuffer sb = new StringBuffer();
        for(int i = 0 ; i < input.length() /2 ; i ++){
            String str = input.substring(i*2, i*2+2);
            String binStr = Integer.toBinaryString(Integer.parseInt(str, 16));
            binStr = String.format("%08d", Integer.parseInt(binStr));
            sb.append(binStr + " ");
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

    /**
     * 二进制字符串转换为字符串
     * @param binCode 二进制字符串
     * @param state 比特率
     * @return
     */
    private static String bin2str(String binCode,int state){
        binCode = binCode.replace(" ", "");
        Map<String,String> map = null;
        switch(state){
            case 4:
                map = RfidConstant.map4Value;
                break;
            case 5:
                map = RfidConstant.map5Value;
                break;
            case 6:
                map = RfidConstant.map6Value;
                break;
            case 7:
                map = RfidConstant.map7Value;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < binCode.length() / state; i++) {
            String tempBar = binCode.substring(i*state, i*state + state);
            String aa = StringUtils.transString(map.get(tempBar));
            sb.append(aa);
        }
        System.out.println("===>> " + sb);
        return sb.toString();
    }


}
